﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Collections;
using Engine.Objects;
using Engine.Voxel;
using Engine.MarchCube;
namespace Engine.Objects
{
    public class BaseDrawObject : DrawableGameComponent, Interface.IEngineObject
    {
        private bool  m_WireFrame;

        public bool  WireFrame
        {
            get { return m_WireFrame; }
            set { m_WireFrame = value; }
        }
        
        string o_Name;
        Vector3 o_Position;
        Quaternion o_Rotation;
        Matrix o_Transform;
        Vector3 o_Scale;
        BasicEffect _effect;
        VertexBuffer _VB;
        IndexBuffer _IB;
        IndexBuffer[] _IBS;
        bool _needRebild;
        public bool NeedRebild { get { return _needRebild; } set { _needRebild = value; } }
        public IndexBuffer[] IBS
        {
            get { return _IBS; }
            set { _IBS = value; }
        }
        public string Name
        {
            get
            {
                return o_Name;
            }
            set
            {

            }
        }

        public bool isGUI
        {
            get { return false; }
        }

        public Vector3 Position
        {
            get
            {
                return o_Position;
            }
            set
            {
                o_Position = value;
                CalkMatrix();
            }
        }

        public Quaternion Rotation
        {
            get
            {
                return o_Rotation;
            }
            set
            {
                o_Rotation = value;
                CalkMatrix();
            }
        }

        public Matrix Transform
        {
            get
            {
                return o_Transform;
            }
            set
            {
                o_Transform = value;
            }
        }

        public Vector3 Scale
        {
            get
            {
                return o_Scale;
            }
            set
            {
                o_Scale = value;
                CalkMatrix();
            }
        }

        public VertexBuffer VB
        {
            get { return _VB; }
            set { _VB = value; }
        }
        public IndexBuffer IB
        {
            get { return _IB; }
            set { _IB = value; }
        }
        public BaseDrawObject(NOWAEngine _game, string _name)
            : this(_game, _name, Vector3.Zero, Vector3.One, Quaternion.Identity)
        {

        }
        
        public unsafe BaseDrawObject(NOWAEngine _game, string _name, Vector3 pos, Vector3 scal, Quaternion rot)
            : base(_game)
        {
            o_Name = _name;
            _needRebild = true;
            o_Position = pos;
            o_Rotation = rot;
            o_Scale = scal;
            _effect = new BasicEffect(Game.GraphicsDevice);           
                 
  
        }
        public bool this[int index]
        {
            get{return true;}
            set { bool r = value; }
         
        }
        public override void Update(GameTime gameTime)
        {
            if (_needRebild)
            {
               
                Rebild();
                _needRebild = false;
            }

            base.Update(gameTime);
        }
        public virtual unsafe void Rebild()
        {

            

        }
       
     
        public override void Draw(GameTime gameTime)
        {
            NOWAEngine nn = Game as NOWAEngine;
            DEFAULTCamera cam = (DEFAULTCamera)(((Engine.NOWAEngine)Game).Manager.GetComponent("CameraManager")).GetMaincamera();
              
            //  

            RasterizerState rast = new RasterizerState();
            if (m_WireFrame)
            {
                rast.FillMode = FillMode.WireFrame;
            }
            else
            {
                rast.FillMode = FillMode.Solid;
            }
           // 
            rast.CullMode = CullMode.None;
            GraphicsDevice.RasterizerState = rast;
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            _effect.View = cam.ViewMatrix;
            _effect.Projection = cam.ProjectionMatrix;
            
            if (!_needRebild && _VB != null)
            {

                nn.GraphicsDevice.SetVertexBuffer(_VB);
                if (_IBS != null)
                {
                    for (int i = 0; i < _IBS.Length; i++)
                    {
                         nn.GraphicsDevice.Indices = _IBS[i];
                    foreach (EffectPass pass in _effect.Techniques[0].Passes)
                    {
                        pass.Apply();
                        nn.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _VB.VertexCount, 0, _IBS[i].IndexCount / 3);

                    }
                    }
                }
                else
                {
                    nn.GraphicsDevice.Indices = _IB;
                    foreach (EffectPass pass in _effect.Techniques[0].Passes)
                    {
                        pass.Apply();
                        nn.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _VB.VertexCount, 0, _IB.IndexCount / 3);

                    }
                }

            }


            base.Draw(gameTime);
        }
        private void CalkMatrix()
        {
            _effect.World = Matrix.CreateScale(Scale) * Matrix.CreateFromQuaternion(o_Rotation) * Matrix.CreateTranslation(o_Position);
            o_Transform = _effect.World;
        }

        public new void LoadContent()
        {
            CalkMatrix();
            //_effect.World = Matrix.Identity;
            _effect.VertexColorEnabled = true;
        }

    }


}
